package com.hnn;

import cn.hutool.core.io.resource.UrlResource;
import javafx.scene.image.PixelFormat;
import sun.reflect.Reflection;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Proxy;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URL;
import java.net.URLClassLoader;
import java.nio.file.Paths;

/**
 * @author hnn
 * @version 1.0
 * @date 2024-01-18 08:59
 */
public class TestCallJni {

    public final static String SCRIPT_CLASS_NAME = "cn.com.reformer.park.cost.ParkCost";

    public static void main(String[] args) throws Exception {
        System.out.println(System.getProperty("java.library.path"));
        System.out.println(System.getProperty("sun.boot.library.path"));

        Test2();
    }

    private static void Test1() throws Exception {
        // 初始化方法
        Class<?>[] init = new Class[2];
        init[0] = String.class;
        init[1] = String.class;

        URI uri1 = Paths.get("D:\\work\\Test\\jni\\script-v1.3.2000.jar").toUri();
        URL url1 = uri1.toURL();
        ClassLoader cl1 = URLClassLoader.newInstance(new URL[]{url1});
        Class<?> class1 = cl1.getParent().loadClass(SCRIPT_CLASS_NAME);
        Object o1 = class1.newInstance();

        Method mInit = class1.getMethod("initDll", init);
        Object h1 = mInit.invoke(o1, "C:\\Windows\\System32", "Holidays.dll");

        URI uri2 = Paths.get("D:\\work\\Test\\jni\\2\\script-v1.3.2000.jar").toUri();
        URL url2 = uri2.toURL();
        ClassLoader cl2 = URLClassLoader.newInstance(new URL[]{url2});
        Class<?> class2 = cl2.loadClass(SCRIPT_CLASS_NAME);

        Object o2 = class2.newInstance();
        Method mInit2 = class2.getMethod("initDll", init);
        Object h2 = mInit2.invoke(o2, "C:\\Windows\\System32", "Holidays.dll");

        System.out.println(cl1.hashCode());
        System.out.println(cl2.hashCode());
        System.out.println(class1.hashCode());
        System.out.println(class2.hashCode());
        System.out.println(h1);
        System.out.println(h2);
    }

    private static void Test2() throws Exception {
        // 初始化方法
        Class<?>[] init = new Class[2];
        init[0] = String.class;
        init[1] = String.class;


        URI uri1 = Paths.get("D:\\work\\Test\\jni\\script-v1.3.2000.jar").toUri();
        URL url1 = uri1.toURL();


        ClassLoader cl1 = URLClassLoader.newInstance(new URL[]{url1});
        Class<?> class1 = cl1.loadClass("com.BlowJobs.Holidays");
        Object o1 = class1.newInstance();

         Class<?> ShowI =  cl1.loadClass("com.BlowJobs.Holidays$ShowI");

        Method mshowMe = class1.getMethod("showMe", ShowI);
        mshowMe.invoke(o1, Proxy.newProxyInstance(cl1, new Class[]{ShowI}, new InvocationHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                if(method.getName().equals("doShow")){
                    return args[0]+"bye";
                }
                return null;
            }
        }));

        Method mLoad = class1.getMethod("load", init);
        //mLoad.invoke(o1, "C:\\Windows\\System32", "Holidays.dll");
        Method mInit = class1.getMethod("init");
        Object h1=mInit.invoke(o1);


        URI uri2 = Paths.get("D:\\work\\Test\\jni\\2\\script-v1.3.2000.jar").toUri();
        URL url2 = uri2.toURL();
        ClassLoader cl2 = URLClassLoader.newInstance(new URL[]{url2});
        Class<?> class2 = cl2.loadClass("com.BlowJobs.Holidays");
        Object o2 = class2.newInstance();

//        Method mLoad2 = class2.getMethod("load", init);
//        mLoad2.invoke(o2, "C:\\Windows\\System32", "Holidays.dll");
//        Method mInit2 = class2.getMethod("init");
//        Object h2=mInit2.invoke(o2);

        System.out.println(cl1.hashCode());
        System.out.println(cl2.hashCode());
        System.out.println(class1.hashCode());
        System.out.println(class2.hashCode());
        System.out.println(h1);
//        System.out.println(h2);

        ClassLoader b= o1.getClass() .getClassLoader().getParent().getParent();
    }
}
